package ml.classification;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;

import ml.classification.filter.PostProcessingFilter;
import ml.classification.filter.PseudoGaussianVotingFilter;
import ml.classification.filter.SpecialisedSpeechFilter;

public class MainClassificationEvaluation {

	private static final boolean USE_TEST_DATA = true;
	private static final boolean USE_TRAINING_DATA = false;
	private static final boolean USE_CONTEST_DATA = false;
	private static final boolean USE_MERGED_DATA = true;
	private static final boolean USE_MERGED_DATA_NEW = false;

	private static final boolean WRITE_OUTPUT_FILES = true;

	private static final String OUTPUT_DIRECTORY = "D:/workspace/machine_learning_project/output/";
	private static final String MODEL_DIRECTORY = "D:/workspace/machine_learning_project/src/ml/models/";
	private static final String DATA_DIRECTORY = "C:/Users/Martin/Dropbox/machine_learning/data/";

	// private static final String OUTPUT_DIRECTORY =
	// "C:/users/moser/workspace/machine_learning_project/output/";
	// private static final String MODEL_DIRECTORY =
	// "C:/users/moser/workspace/machine_learning_project/src/ml/models/";
	// private static final String DATA_DIRECTORY =
	// "C:/users/moser/Dropbox/machine_learning/data/";

	public static void main(final String[] args) throws Exception {

		final List<ClassificationStatistics> listStats = new ArrayList<>();
		final List<String> listFileNames = getFileNames();

		final String musicModelFileName = MODEL_DIRECTORY
				+ "music.SMO.Music.Model.low.FP.rate.20130605.1032.model";
		final String speechModelFileName = MODEL_DIRECTORY
				+ "speech.stacking.5pct.based.on.training_data.20130606.1622.model";

		// for (int musicN = 15; musicN <= 15; musicN += 3) {
		for (int musicN = 25; musicN <= 25; musicN += 25) {
			for (int musicIterations = 3; musicIterations <= 3; musicIterations += 1) {
				for (int speechN = 5; speechN <= 5; speechN += 5) {
					for (int speechIterations = 1; speechIterations <= 1; speechIterations += 1) {
						for (double threshold = 1.00; threshold <= 1.00; threshold += 0.1) {

							final PostProcessingFilter musicFilter = new PseudoGaussianVotingFilter(
									musicN, musicIterations, false);
							final PostProcessingFilter speechFilter = new SpecialisedSpeechFilter(
									speechN, speechIterations, threshold);

							for (final String fileName : listFileNames) {

								final String musicTestDataFileName = buildMusicFilePath(fileName);
								final String speechTestDataFileName = buildSpeechFilePath(fileName);

								final ClassificationStatistics stats = Classification
										.classifyAndPostprocess(fileName,
												WRITE_OUTPUT_FILES,
												OUTPUT_DIRECTORY,
												USE_CONTEST_DATA,
												musicTestDataFileName,
												speechTestDataFileName,
												musicModelFileName,
												speechModelFileName,
												musicFilter, speechFilter);
								listStats.add(stats);
							}
						}
					}
				}
			}
		}

		System.out.println(ClassificationStatistics.getHeader());
		for (final ClassificationStatistics stats : listStats) {
			System.out.println(stats.toString());
		}

		final BufferedWriter writerStats = new BufferedWriter(new FileWriter(
				OUTPUT_DIRECTORY + "Stats.csv"));
		writerStats.write(ClassificationStatistics.getHeader() + "\n");
		for (final ClassificationStatistics stats : listStats) {
			writerStats.write(stats.toString() + "\n");
		}
		writerStats.flush();
		writerStats.close();
	}

	private static String buildSpeechFilePath(final String fileName) {
		String speechTestDataFileName = DATA_DIRECTORY
				+ "test_data/speech/original/" + fileName + ".speech.arff";
		if (USE_CONTEST_DATA) {
			speechTestDataFileName = DATA_DIRECTORY
					+ "contest_data/speech/original/" + fileName
					+ "_speech.arff";
		}
		if (USE_TRAINING_DATA) {
			speechTestDataFileName = DATA_DIRECTORY
					+ "training_data/speech/original/" + fileName
					+ ".speech.arff";
		}
		return speechTestDataFileName;
	}

	private static String buildMusicFilePath(final String fileName) {
		String musicTestDataFileName = DATA_DIRECTORY
				+ "test_data/music/original/" + fileName + ".music.arff";
		if (USE_MERGED_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "test_data/music/original.merged/" + fileName
					+ ".music.arff";
		}
		if (USE_MERGED_DATA_NEW) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "test_data/music/original.merged.new/" + fileName
					+ ".music.arff";
		}
		if (USE_CONTEST_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "contest_data/music/original/" + fileName + "_music.arff";
			if (USE_MERGED_DATA) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "contest_data/music/original.merged/" + fileName
						+ "_music.arff";

			}
			if (USE_MERGED_DATA_NEW) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "contest_data/music/original.merged.new/" + fileName
						+ "_music.arff";

			}
		}
		if (USE_TRAINING_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "training_data/music/original/" + fileName
					+ ".music.arff";
			if (USE_MERGED_DATA) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "training_data/music/original.merged/" + fileName
						+ ".music.arff";

			}
			if (USE_MERGED_DATA_NEW) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "training_data/music/original.merged.new/" + fileName
						+ ".music.arff";

			}
		}
		return musicTestDataFileName;
	}

	private static List<String> getFileNames() {
		final List<String> listFileNames = new ArrayList<>();
		if (USE_CONTEST_DATA) {
			for (int i = 1; i <= 16; i++) {
				listFileNames.add(String.valueOf(i));
			}

		} else if (USE_TRAINING_DATA) {
			listFileNames.add("ARD-h4");
			listFileNames.add("ARD-h13");
			listFileNames.add("ARD-h16");
			listFileNames.add("ARD-h22");
			listFileNames.add("RTL-h11");
			listFileNames.add("RTL-h20");
			listFileNames.add("RTL-h23");
			listFileNames.add("ZDF-h2");
			listFileNames.add("ZDF-h8");
			listFileNames.add("ZDF-h20");
		} else if (USE_TEST_DATA) {
			listFileNames.add("ARD-h19");
			listFileNames.add("RTL-h5");
			listFileNames.add("RTL-h14");
			listFileNames.add("ZDF-h14");
			listFileNames.add("ZDF-h15");
		}
		return listFileNames;
	}
}
